import random
import re
from django.shortcuts import render
from rest_framework.decorators import action
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework_jwt.views import ObtainJSONWebToken

from carts.utils import merge_cookie_redis_cart
from goods.models import SKU

from orders.models import OrderInfo

from orders.models import OrderGoods
from .models import User
from rest_framework.generics import GenericAPIView,CreateAPIView,RetrieveAPIView,UpdateAPIView, ListAPIView
from rest_framework import mixins
from . import serializers
from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import GenericViewSet
from django_redis import get_redis_connection
class CheckUsernameView(APIView):
    def get(self,request,username):

        #1,根据用户名查询,用户数量
        count = User.objects.filter(username=username).count()

        #2,返回响应
        data = {
            "count":count
        }
        return Response(data,status=status.HTTP_200_OK)

class CheckMobileView(APIView):
    def get(self,request,mobile):

        #1,根据手机号查询,用户数量
        count = User.objects.filter(mobile=mobile).count()

        #2,返回响应
        data = {
            "count":count
        }
        return Response(data,status=status.HTTP_200_OK)

class RegisterUserView(CreateAPIView):
    serializer_class = serializers.RegisterUserSerializer

    # def post(self,request):
        #一, 只继承自了GenericAPIView
        # #1,获取参数
        # dict_data = request.data
        #
        # #2,创建序列化器,校验
        # serializer =  self.get_serializer(data=dict_data)
        # serializer.is_valid(raise_exception=True)
        #
        # #3,数据入库
        # serializer.save()
        #
        # #4,返回响应
        # return Response(serializer.data,status=status.HTTP_201_CREATED)

        #二,使用了mixin + GenericAPIView
        # return self.create(request)

class UserInfoView(RetrieveAPIView):
    serializer_class = serializers.UserInfoSerializer

    permission_classes = [IsAuthenticated] #认证的用户

    def get_object(self):
        return self.request.user

    # def get(self,request):
    #     #一, 单纯使用二级视图实现
    #     # #1,获取用户对象(或者request.user)
    #     # user =  self.get_object()
    #     #
    #     # #2,创建序列化对象
    #     # serializer = self.get_serializer(instance=user)
    #     #
    #     # #3,返回数据
    #     # return Response(serializer.data)
    #
    #     #二,二级视图配合mixin
    #     return self.retrieve(request)

class EmailSendView(UpdateAPIView):
    serializer_class = serializers.EmailSendSerializer
    permission_classes = [IsAuthenticated]
    def get_object(self):
        return self.request.user

    # def put(self,request):
    #     #一, 单纯使用二级视图实现
        # #1,获取数据
        # dict_data = request.data
        # user = self.get_object()
        #
        # #2,获取序列化器
        # serializer = self.get_serializer(instance=user,data=dict_data)
        #
        # #3,校验,入库
        # serializer.is_valid(raise_exception=True)
        # serializer.save()
        #
        # #4,返回
        # return Response(serializer.data)
    #     #二,二级视图配合mixin
        # return self.update(request)

class EmailActiveView(APIView):
    def get(self,request):
        #1,获取参数token
        token = request.query_params.get("token")

        #2,为空校验
        if not token:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        #3,解密token
        user = User.decode_token(token)
        if not user:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        #4,数据入库(修改email_active属性)
        user.email_active = True
        user.save()

        #5,返回响应
        return Response(status=status.HTTP_200_OK)

class AddressView(mixins.CreateModelMixin,
                  mixins.UpdateModelMixin,
                  mixins.DestroyModelMixin,
                  GenericViewSet):
    serializer_class = serializers.AddressSerializer

    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        return self.request.user.addresses.filter(is_deleted=False)

    def list(self,request):

        # 1,获取用户地址信息
        queryset = self.get_queryset()

        #2,获取序列化器
        serializer = self.get_serializer(instance=queryset,many=True)

        #3,返回
        return Response({
            "addresses":serializer.data,
            "limit":20,
            "default_address_id":request.user.default_address_id
        })

    #1,重写地址创建方法,判断用户的地址是否已经达到20个了
    def create(self, request, *args, **kwargs):
        # #1,获取参数
        # dict_data = request.data
        #
        # #2,获取序列化器
        # serializer = self.get_serializer(data=dict_data)
        #
        # #3,校验入库
        # serializer.is_valid(raise_exception=True)
        # serializer.save()
        #
        # #4,返回
        # return Response(serializer.data)

        #1,获取用户地址数量
        count =  request.user.addresses.filter(is_deleted=False).count()

        #2,判断地址的数量
        if count >= 20:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        #3,调用父类方法即可
        return super(AddressView, self).create(request,*args,**kwargs)

    #2,更改用户默认地址
    @action(methods=['put'],detail=True) #格式: addresses/pk/status
    def status(self,request,pk):
        request.user.default_address_id = pk
        request.user.save()
        return Response(status=status.HTTP_200_OK)

    #3,修改地址的标题
    @action(methods=["put"],detail=True)
    def title(self,request,pk):
        #1,获取参数
        dict_data = request.data
        address = self.get_object()

        #2,创建序列化器
        serializer = serializers.AddressTitleSerializer(instance=address,data=dict_data)

        #3,校验数据,入库
        serializer.is_valid(raise_exception=True)
        serializer.save()

        #4,返回
        return Response(serializer.data)

    #4,重写destory方法,为了逻辑删除
    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.is_deleted = True
        instance.save()
        return Response(status=status.HTTP_204_NO_CONTENT)


class TestView(APIView):
    def get(self,request,name,age):
        print(self.kwargs) #获取的就是地址中,写带的资源参数
        return Response("%s,%s"%(name,age))

class UserBrowerHistoryView(CreateAPIView):
    serializer_class =serializers.UserBrowerHistorySerializer

    # def post(self,request):
    #
    #     #1,获取参数
    #     dict_data = request.data
    #
    #     #2,获取序列化器,校验
    #     serializer = self.get_serializer(data=dict_data)
    #     serializer.is_valid(raise_exception=True)
    #
    #     #3,入库(保存到redis中)
    #     serializer.save()
    #
    #     #4,返回
    #     return Response(serializer.data)

    def get(self,request):
        #1,获取redis中的数据
        redis_conn = get_redis_connection("history")
        sku_ids = redis_conn.lrange("history_%s"%request.user.id,0,4)

        #2,拼接数据
        sku_list = []
        for sku_id in sku_ids:
            sku = SKU.objects.get(id=sku_id)
            sku_dict = {
                "default_image_url":sku.default_image_url,
                "name":sku.name,
                "price":sku.price,
                "comments":sku.comments,
                "id":sku.id
            }
            sku_list.append(sku_dict)

        #3,返回
        return Response(sku_list)

#重写登陆类视图
class UserObtainJSONWebToken(ObtainJSONWebToken):
    def post(self, request, *args, **kwargs):

        #1,调用父类方法
        response = super().post(request, *args, **kwargs)

        #2,获取序列化器
        serializer = self.get_serializer(data=request.data)

        #3,判断是否认证成功
        if serializer.is_valid():

            #3.1获取user对象
            user = serializer.validated_data.get("user")

            #3.2合并购物车
            response = merge_cookie_redis_cart(request,user,response)

        return response


# 重置密码
class PasswordUpdateView(GenericAPIView):

    # serializer_class = serializers.PasswordUpdateSerializer
    # permission_classes = [IsAuthenticated]
    def put(self,request,pk):
        # 1.获取参数
        user = request.user
        if user and user.is_authenticated:
            old_pwd = request.data.get("old_password")
            pwd = request.data.get("password")
            pwd2 = request.data.get("password2")

            print(user.check_password(old_pwd))

            # 2.校验原密码是否正确
            if not user.check_password(old_pwd):
                return Response({"message": "原密码错误"}, status=status.HTTP_403_FORBIDDEN)
            if not user.is_authenticated:
                return Response({"message": "用户未认证"}, status=status.HTTP_400_BAD_REQUEST)
            # 3.判断新密码和确认密码是否一致
            if pwd != pwd2:
                return Response({"message": "两次密码不一致"}, status=status.HTTP_400_BAD_REQUEST)
            try:
                user.set_password(pwd)
                user.save()
            except:
                return Response({"message": "数据库错误"}, status=status.HTTP_400_BAD_REQUEST)
            return Response({"message": "ok"})
        return Response(status=status.HTTP_403_FORBIDDEN)

    def post(self, request, pk):
        # 获取数据
        dict_data = request.data
        user = User.objects.get(id=pk)

        # 数据校验
        if dict_data.get("password") != dict_data.get("password2"):
            return Response(status=status.HTTP_400_BAD_REQUEST)

        # 数据入库
        user.set_password(dict_data.get("password"))
        user.save()

        return Response(status=status.HTTP_200_OK)
    # def post(self, request, user_id):
    #
    #     # 获取数据
    #     dict_data = request.data
    #     user = User.objects.get(id=user_id)
    #
    #     # 数据校验
    #     if dict_data.get("password") != dict_data.get("password2"):
    #         return Response(status=status.HTTP_400_BAD_REQUEST)
    #
    #     # 数据入库
    #     user.set_password(dict_data.get("password"))
    #     user.save()
    #
    #     return Response(status=status.HTTP_200_OK)


# class ShowOrdersView(ListAPIView):

    # serializer_class = serializers.UserGoodSerilizer
    # permission_classes = [IsAuthenticated]

    # 重写搜索集
    # def get_queryset(self):
        # return OrderInfo.objects.filter(user=self.request.user)
# 展示订单
class ShowOrdersView(GenericAPIView):
    pagination_class = None
    def get(self, request):
        # 获取用户
        user = request.user
        # 获取用户的订单
        order_user = OrderInfo.objects.filter(user_id=user.id).all()
        order_dict = []

        for orders in order_user:
            sku_list = []
            # 支付方式判斷
            # if orders.pay_method == orders.pay_method:
            #     status = orders.ORDER_STATUS_ENUM["UNPAID"]
            # else:
            #     status = orders.ORDER_STATUS_ENUM["UNSEND"]
            # print(orders)
            results = {
                "create_time": orders.create_time,
                "order_id": orders.order_id,
                "total_amount": orders.total_amount,
                "pay_method": orders.pay_method,
                "freight": orders.freight,
                "skus": sku_list,
                'status': orders.status
            }
            # 获取商品订单
            order_goods = OrderGoods.objects.filter(order=orders)
            for skus in order_goods:

                count = skus.count
                price = skus.price

                order_sku = {
                    "price": price,
                    "count": count,
                    'sku': {
                        'name': skus.sku.name,
                        'default_image_url': skus.sku.default_image_url,
                    }
                }
                sku_list.append(order_sku)
            order_dict.append(results)

        return Response({"results": order_dict})

#以下四个视图完成忘记密码操作
class FindPassWord(APIView):

    def get(self, request, username):

        try:

            if re.match(r'^1[345789]\d{9}$', username):

                user = User.objects.get(mobile=username)

            else:

                user = User.objects.get(username=username)

        except User.DoesNotExist:

            return Response(status=status.HTTP_404_NOT_FOUND)

        dict_data = request.query_params

        # 获取redis中的短信验证码
        redis_conn = get_redis_connection("code")
        image_text = redis_conn.get("image_code_%s" % dict_data['image_code_id'])

        if not image_text:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        # 删除验证码
        redis_conn.delete("image_code_%s" % dict_data['image_code_id'])

        # 校验图片码
        if image_text.decode().upper() != dict_data['text'].upper():
            return Response(status=status.HTTP_400_BAD_REQUEST)

        from rest_framework_jwt.settings import api_settings
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        mobile = user.mobile
        redis_conn.setex(token, 300, mobile)

        return Response({
            "mobile": user.mobile,
            "access_token": token
        })

class FindPassWordSms(APIView):

    def get(self, request):

        # 获取数据
        dict_data = request.query_params
        access_token = dict_data.get("access_token")

        redis_conn = get_redis_connection("code")
        mobile = redis_conn.get(access_token).decode()

        # 判断是否频繁发送
        send_flag = redis_conn.get("send_flag_%s" % mobile)
        if send_flag:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        # 发送短信
        sms_code = "%06d" % random.randint(0, 99999)
        print("sms_code = %s" % sms_code)

        # 使用celery进行短信发送
        # from celery_tasks.sms.send_sms import send_sms_code
        # result = send_sms_code.delay(mobile, sms_code)

        # if result == -1:
        #     return http.HttpResponseBadRequest("发送短信失败")

        # 短信入库
        redis_conn.setex("sms_code_%s" % mobile, 300, sms_code)
        redis_conn.setex("send_flag_%s" % mobile, 60, True)

        sms_redis = redis_conn.get("sms_code_%s" % mobile)

        # 返回响应
        return Response(status=status.HTTP_200_OK)


class CheckPassWord(APIView):
    def get(self, request, username):

        try:

            if re.match(r'^1[345789]\d{9}$', username):

                user = User.objects.get(mobile=username)

            else:

                user = User.objects.get(username=username)

        except User.DoesNotExist:

            return Response(status=status.HTTP_404_NOT_FOUND)

        dict_data = request.query_params
        sms_code = dict_data.get('sms_code')
        # access_token = dict_data.get('access_token')

        # 获取redis中的短信验证码
        redis_conn = get_redis_connection("code")
        mobile = user.mobile
        sms_redis = redis_conn.get("sms_code_%s" % mobile)

        # 判断sms_redis的存在性
        if not sms_redis:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        # 校验短信验证码
        if sms_redis.decode() != sms_code:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        from rest_framework_jwt.settings import api_settings
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        return Response({
            "user_id": user.id,
            "access_token": token,
        })

